﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WhittleList.Bll
{
    public class SiteRepository : BaseRepository, WhittleList.Bll.ISiteRepository
    {
        private IQueryable<Site> _Sites;
        private IQueryable<Project> _Projects;
        private IQueryable<UserProjectRole> _UserProjectsRole;
        private IQueryable<Section> _Sections;
        private IQueryable<Item> _Items;

        #region Constructors
        public SiteRepository() : this(new WhittleListDataContext())
        {
        }

        public SiteRepository(IWhittleListDataContext dbContext) : base(dbContext)
        {
            _Sites = _DBContext.Sites.Where(x => !x.Deleted);
            _Projects = _DBContext.Projects.Where(x => !x.Deleted);
            _UserProjectsRole = _DBContext.UserProjectRoles.Where(x => !x.Deleted);
            _Sections = _DBContext.Sections.Where(x => !x.Deleted);
            _Items = _DBContext.Items.Where(x => !x.Deleted);
        }

        #endregion

        #region Insert Methods
        public void Insert(Site site)
        {
            if (_DBContext != null)
            {
                _DBContext.Insert(site);
            }
        }

        public void Insert(Project site)
        {
            if (_DBContext != null)
            {
                _DBContext.Insert(site);
            }
        }

        public void Insert(UserProjectRole projectRole)
        {
            if (_DBContext != null)
            {
                _DBContext.Insert(projectRole);
            }
        }

        public void Insert(Section section)
        {
            if (_DBContext != null)
            {
                _DBContext.Insert(section);
            }
        }

        public void Insert(Item item)
        {
            if (_DBContext != null)
            {
                _DBContext.Insert(item);
            }
        }
        #endregion

        #region site GetMethods
        public Site Site_GetById(int id)
        {
            return _Sites.SingleOrDefault(x => x.Id == id);
        }

        public Site Site_GetByUrl(string url)
        {
            return _Sites.SingleOrDefault(x => x.Url == url);
        }

        public Site Site_GetByName(string name)
        {
            return _Sites.SingleOrDefault(x => x.Name == name);
        }

        public IQueryable<Site> Site_GetAllByOwnerId(int id)
        {
            return _Sites.Where(x => x.OwnerId == id).OrderBy(x => x.Name);
        }

        public IQueryable<Site> Site_GetAllByOwner(User owner)
        {
            if (owner != null)
            {
                return Site_GetAllByOwnerId(owner.Id);
            }
            return null;
        }
        #endregion

        #region project Get_Methods
        public Project Project_GetById(int id)
        {
            return _Projects.SingleOrDefault(x => x.Id == id);
        }

        public IQueryable<Project> Project_GetAllBySiteId(int siteId)
        {
            return _Projects.Where(x => x.SiteId == siteId);
        }

        public IQueryable<Project> Project_GetAllBySite(Site site)
        {
            return Project_GetAllBySiteId(site.Id);
        }

        public IQueryable<Project> Project_GetAllByUser(User user, bool? approved)
        {
            return Project_GetAllByUserId(user.Id, approved);
        }

        public IQueryable<Project> Project_GetAllByUserId(int userId, bool? approved)
        {
            return _UserProjectsRole.Where(x => x.UserId == userId && x.Approved == (approved ?? x.Approved)).Select(x => x.Project).Where(x => !x.Deleted);
        }

        public IQueryable<User> Project_GetAllUsersByProjectId(int projectId, bool? approved)
        {
            var upr = _UserProjectsRole.Where(x => x.ProjectId == projectId && x.Approved == (approved ?? x.Approved));
            return upr.Select(x => x.User).Where(x => !x.Deleted);
        }
        #endregion

        #region Section Get Functions
        public Section Section_GetById(int id)
        {
            return _Sections.SingleOrDefault(x => x.Id == id);
        }

        public IQueryable<Section> Section_GetAllByProjectId(int projectId)
        {
            return _Sections.Where(x => x.ProjectId == projectId).OrderBy(x => x.Sequence);
        }

        #endregion
        public bool UserHasRole(User user, Site site)
        {
            if (site.OwnerId == user.Id)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        #region Item Get MEthods
        public Item Item_GetById(int id)
        {
            return _Items.SingleOrDefault(x => x.Id == id);
        }

        public IQueryable<Item> Item_GetByAllBySectionId(int sectionId)
        {
            return _Items.Where(x => x.SectionId == sectionId);
        }
        #endregion

    }
}
